package edu.hawaii.senin.iclouds.basics;

import java.io.BufferedWriter;
import java.io.IOException;
import java.util.ArrayList;

/**
 * Defines reaction.
 * 
 * @author Pavel Senin
 * 
 */

public class Reaction {

  /**
   * Describes the molecule.
   */
  private String name;

  /**
   * Contains reactants used in the reaction.
   */
  private final ArrayList<String> reactants;

  /**
   * Contains products used in the reaction.
   */
  private final ArrayList<String> products;

  /**
   * Reaction rate.
   */
  private Double rate;

  /**
   * Reaction type.
   */
  private String type;

  /**
   * REaction energy barrier.
   */
  private Double eBarrier;

  /**
   * Probability of overcoming energy barrier.
   */
  private Double chi;

  /**
   * Instatiates Molecule with given Reactants and Products List.
   * 
   * @param description molecule description.
   * @param rate reaction rate.
   * @param eBarrier reaction energy barrier.
   * @param type reaction type.
   * @param reactants ArrayList specifying reactants.
   * @param products ArrayList specifying products.
   */
  public Reaction(String description, Double eBarrier, Double rate, String type,
      ArrayList<String> reactants, ArrayList<String> products) {
    this.name = description;
    this.rate = rate;
    this.eBarrier = eBarrier;
    this.type = type;

    this.reactants = reactants;
    this.products = products;
  }

  /**
   * Sets the reaction rate.
   * 
   * @param rate rate to set.
   */
  public void setRate(Double rate) {
    this.rate = rate;
  }

  /**
   * Returns the current rate.
   * 
   * @return current rate.
   */
  public Double getRate() {
    return this.rate;
  }

  /**
   * Sets new description for molecule.
   * 
   * @param description the new description.
   */
  public void setName(String description) {
    this.name = description;
  }

  /**
   * Gets the description for molecule.
   * 
   * @return the molecule description.
   */
  public String getName() {
    return this.name;
  }

  /**
   * Sets the type for reaction.
   * 
   * @param type - new type to set.
   */
  public void setType(String type) {
    this.type = type;
  }

  /**
   * Gets the type for reaction.
   * 
   * @return the molecule description.
   */
  public String getType() {
    return this.type;
  }

  /**
   * Sets new energy barrier.
   * 
   * @param barrier new barrier to set.
   */
  public void setEBarrier(Double barrier) {
    this.eBarrier = barrier;
  }

  /**
   * Returns current eBarrier value.
   * 
   * @return current value.
   */
  public Double getEBarrier() {
    return this.eBarrier;
  }

  /**
   * Returns current Chi value.
   * 
   * @return current value.
   */
  public Double getChi() {
    return this.chi;
  }

  /**
   * Sets new energy barrier.
   * 
   * @param barrier new barrier to set.
   */
  public void setChi(Double barrier) {
    this.chi = barrier;
  }

  /**
   * Returns all reactants.
   * 
   * @return the Object[] array.
   */
  public ArrayList<String> getReactants() {
    return this.reactants;
  }

  /**
   * Returns all products.
   * 
   * @return the Object[] array.
   */
  public ArrayList<String> getProducts() {
    return this.products;
  }

  public String toText() {
    StringBuffer sb = new StringBuffer(1000);
    // this.name = description;
    // this.rate = rate;
    // this.eBarrier = eBarrier;
    // this.type = type;
    // this.reactants = reactants;
    // this.products = products;
    sb.append(this.name + ": ");
    sb.append(", type: " + this.type);
    sb.append(", eBarrier: " + this.eBarrier + "\n   reactants: [");
    for (String s : this.reactants) {
      sb.append(s + ", ");
    }
    sb.append("], product(s): [");
    for (String s : this.products) {
      sb.append(s + ", ");
    }
    sb.append("]\n\n");
    // sb.append(", abundance: " + this.abundance);
    // sb.append(", fr: " + this.fraction);
    // sb.append(", vel: " + this.velocity + "\n");

    return sb.toString();
  }

  public void dumpToWriter(BufferedWriter out) throws IOException {
    // this.name = description;
    // this.rate = rate;
    // this.eBarrier = eBarrier;
    // this.type = type;
    // this.reactants = reactants;
    // this.products = products;
    // <reaction>
    // <name>DCO_DCO</name>
    // <rate>1.0</rate>
    // <reactants>
    // <atom>D</atom>
    // <molecule>CO</molecule>
    // </reactants>
    // <products>
    // <molecule>DCO</molecule>
    // </products>
    // <type>QT</type>
    // </reaction>
    out.write("<reaction>\n");
    out.write("<name>" + this.name + "</name>\n");
    out.write("<type>" + this.type + "</type>\n");
    out.write("<reactants>\n");
    for (String s : this.reactants) {
      if (s.length() == 1) {
        out.write("<atom>" + s + "</atom>\n");
      }
      else {
        out.write("<molecule>" + s + "</molecule>\n");
      }
    }
    out.write("</reactants>\n");
    out.write("<products>\n");
    for (String s : this.products) {
      if (s.length() == 1) {
        out.write("<atom>" + s + "</atom>\n");
      }
      else {
        out.write("<molecule>" + s + "</molecule>\n");
      }
    }
    out.write("</products>\n");
    out.write("<energy_barrier>" + this.eBarrier + "</energy_barrier>\n");
    out.write("</reaction>\n");

  }
}
